package cn.tianyigps.obd.utils;

import io.netty.buffer.ByteBuf;
import io.netty.util.ReferenceCountUtil;

public class MessageCoding {

    public static String getHexStr(ByteBuf buf) {
        try {
            MessageCoding messageCoding = new MessageCoding();
            byte[] bytes = new byte[buf.readableBytes()];
            buf.readBytes(bytes);
            if (bytes.length > 0) {
                return messageCoding.bytesToHexString(bytes).toUpperCase();
            } else {
                return null;
            }
        } finally {
            ReferenceCountUtil.release(buf);
        }
    }

    public static byte[] getBytes(ByteBuf buf) {
        byte[] bytes = new byte[buf.readableBytes()];
        buf.readBytes(bytes);
        return bytes;
    }
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public int byteArrayToInt(byte[] b) {
        return b[3] & 0xFF |
                (b[2] & 0xFF) << 8 |
                (b[1] & 0xFF) << 16 |
                (b[0] & 0xFF) << 24;
    }

    public int byteToInt(byte b) {
        //Java 总是把 byte 当做有符处理；我们可以通过将其和 0xFF 进行二进制与得到它的无符值
        return b & 0xFF;
    }

    /**
     * 把16进制字符串转换成字节数组
     *
     * @param hexString
     * @return byte[]
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || "".equals(hexString)) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }



    public static String convertStringToHex(String str){

        char[] chars = str.toCharArray();

        StringBuffer hex = new StringBuffer();
        for(int i = 0; i < chars.length; i++){
            hex.append(Integer.toHexString((int)chars[i]));
        }
        return hex.toString();
    }

    public static String convertHexToString(String hex){

        StringBuilder sb = new StringBuilder();
        StringBuilder temp = new StringBuilder();

        //49204c6f7665204a617661 split into two characters 49, 20, 4c...
        for( int i=0; i<hex.length()-1; i+=2 ){

            //grab the hex in pairs
            String output = hex.substring(i, (i + 2));
            //convert hex to decimal
            int decimal = Integer.parseInt(output, 16);
            //convert the decimal to character
            sb.append((char)decimal);

            temp.append(decimal);
        }
        return sb.toString();
    }


    public String firstCharUpper(String str){
        if(str!=null&&Character.isLowerCase(str.charAt(0))){ //根据需要判断是大写还是小写，下面可以做相应的修改
            char[] charArray = str.toCharArray();
            if(charArray!=null){
                charArray[0]-=32; //此处是小写转大写，如果是大写转小写则是+=32，上面需要判断一下
                return String.valueOf(charArray);
            }
        }
        return str;
    }

    //设备号转伪ip
    public  String  numToIp(String equId) throws Exception{
        StringBuffer hexStr = new StringBuffer();
        if(equId.length()==11){
            equId = equId.substring(1);
            int number = Integer.parseInt(equId.substring(0, 2));
            equId =equId.substring(2);
            int [] equ = new int[equId.length()/2];
            for (int i = 0; i < equId.length()/2; i++) {
                String a =equId.substring(i*2,(i+1)*2);
                equ[i] =Integer.parseInt(equId.substring(i*2,(i+1)*2));
            }
            if(number-30<16){
                number = number -30;
            }else{
                number = number -46;
            }
            char[] chars = Integer.toBinaryString(number).toCharArray();
            for (int i = 0; i < equ.length; i++) {
                int c =0;
                if(number<8){
                    if(i==0){
                        c=0;
                    }else{
                        c =chars[i-1]-'0';
                    }
                }else{
                    c =chars[i]-'0';
                }
                int ch =equ[i] +0x80*c;
                hexStr.append(String.format("%02x", ch).toUpperCase());
            }
            return hexStr.toString() ;
        }else{
            throw new Exception("长度错误");
        }
    }



    //获取校验码,可能为3
    public static byte[] byteToCheck(byte[] datas){
        byte temp=datas[0];

        for (int i = 1; i <datas.length-2; i++) {
            temp ^=datas[i];
        }
        datas [datas.length-2] =temp;
        return datas;
    }
    //下发指令末尾默认加上00，需要从将倒数第三位改成校验码获取校验码
    public static byte[] byteToCheckCmdSend(byte[] datas){
        byte temp=datas[0];

        for (int i = 1; i <datas.length-2; i++) {
            temp ^=datas[i];
        }
        datas [datas.length-2] =temp;
        return datas;
    }
    //获取校验码
    public String  byteToStrCheck(byte[] datas){
        byte temp=datas[0];

        for (int i = 1; i <datas.length-2; i++) {
            temp ^=datas[i];
        }
        byte [] b = new byte[1];
        b[0]=temp;
        return new MessageCoding().bytesToHexString(b);
    }
    public String stripString(String str){
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < str.length()/2; i++) {
            stringBuffer.append(str.substring(2*i,2*(i+1)));
            stringBuffer.append(" ");
        }
        return stringBuffer.toString();    }

    public  String makeChecksum(String data) {
        if (data == null || data.equals("")) {
            return "";
        }
        int total = 0;
        int len = data.length();
        int num = 0;
        while (num < len) {
            String s = data.substring(num, num + 2);
            total += Integer.parseInt(s, 16);
            num = num + 2;
        }
        /**
         * 用256求余最大是255，即16进制的FF
         */
        int mod = 256-total % 256;
        String hex = Integer.toHexString(mod);
        len = hex.length();
        // 如果不够校验位的长度，补0,这里用的是两位校验
        if (len < 2) {
            hex = "0" + hex;
        }
        return hex;
    }

    public static String longToBINstr(Long n){
        String str = "";
        for(int i = 31;i >= 0; i--){
            str +=(n >>> i & 1)+"";
        }
        return str;
    }
//    public static String hexToString(String hexStr) {
//        String str = "0123456789ABCDEF";
//        char[] hexs = hexStr.toCharArray();
//        byte[] bytes = new byte[hexStr.length() /2];
//        int n;
//        for (int i = 0; i < bytes.length ; i++) {
//            n = str.indexOf(hexs[2*i]) * 16;
//            n += str.indexOf(hexs[2*i +1]);
//            bytes[i] = (byte)(n & 0xff);
//        }
//        return new String(bytes).toUpperCase();
//    }
}
